import cv2 as cv
import numpy as np


# canny梯度检测
# ①高斯模糊 - GaussianBlur（canny边缘提取算法对噪声敏感，因此在进行边缘提取之前使用高斯模糊对图像进行降噪）
# ②灰度转换 - cvtColor
# ③计算梯度 – Sobel/Scharr
# ④非最大信号抑制
# ⑤高低阈值输出二值图像（可以得到一个边缘连续且虚假边缘小的梯度图像）
def edge_demo(image):
    blurred = cv.GaussianBlur(image, (3, 3), 0)  # 第二个参数时size，第三个参数时高斯函数的标准差，如果给定了size，则可以根据size算出标准差，因此不需要额外给定
    gray = cv.cvtColor(blurred, cv.COLOR_RGB2GRAY)  # 也可以不转换为灰度图像，直接用高斯模糊后的彩色图像进行canny运算
    # xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0) # x方向梯度，canny不能用float
    # ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1) # y方向梯度
    # edge_output = cv.Canny(xgrad, ygrad, 50, 150)  # 后面两个参数分别时低阈值和高阈值，其中高阈值一般是低阈值的三倍（canny函数两种之一）
    edge_output = cv.Canny(gray, 50, 150)  # canny函数两种之一
    cv.imshow("Canny Edge", edge_output)
    dst = cv.bitwise_and(image, image, mask=edge_output)  # 逻辑运算与（mask也参与运算）
    cv.imshow("Color Edge", dst)


src = cv.imread('imgs/test008.jpg')
cv.imshow('input_image', src)
edge_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()